﻿using ImperialServer.Common.Entities;
using ImperialServer.Data.DAO;
using ImperialServer.Data.Interfaces;
using ImperialUtilities.Exceptions;
using ImperialUtilities.Utilities;
using ImperialWebSite.Content.Resources;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;

namespace ImperialWebSite.Controllers
{
    public class StatusController : BaseController
    {
        private IRegistryAccess _daoRegistryAccess;
        private EventViewer _logger;

        public StatusController()
        {
            _logger = new EventViewer("ImperialWebSite.Controllers");
            _daoRegistryAccess = new RegistryAccess(ConfigurationManager.ConnectionStrings["ImperialConnection"].ConnectionString);
        }

        /// <summary>
        /// Metodo que crea un objeto de tipo StatusEntity
        /// </summary>
        /// <param name="statusNameText">nombre de el estatus</param>
        /// <returns>objeto lleno</returns>
        internal StatusEntity CreateNewStatus(string statusNameText)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "CreateNewStatus"));

            StatusEntity newStatus = null;
            try
            {
                newStatus = new StatusEntity
                {
                    StatusName = statusNameText
                };

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("CreateNewStatus", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "CreateNewStatus"));
            }
            return newStatus;
        }

        /// <summary>
        /// Metodo que se encarga de realizar la llamada al servidor para insertar un nuevo estatus
        /// </summary>
        /// <param name="newStatus">objeto con los datos a insertar</param>
        /// <returns>true si fue exitosa, false si no</returns>
        internal bool InsertNewStatus(StatusEntity newStatus)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "InsertNewStatus"));

            bool isSuccess = false;
            try
            {
                isSuccess = _daoRegistryAccess.InsertNewStatus(newStatus);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("InsertNewStatus", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "InsertNewStatus"));
            }
            return isSuccess;
        }

        /// <summary>
        /// Metodo que indica si un statusName ya se encuentra registrado
        /// </summary>
        /// <param name="statusName">nombre de estatus</param>
        /// <param name="currentStatuses">lista de estatus ya registradas</param>
        /// <returns>true si existe, false si no</returns>
        internal bool StatusAlreadyRegistered(string statusName, object currentStatuses)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "StatusAlreadyRegistered"));

            bool found = false;
            try
            {
                DataTable dtCurrentStatuses = (DataTable)currentStatuses;
                DataRow[] drCurrentStatus = dtCurrentStatuses.Select("statusName = '" + statusName.ToLower() + "'");
                found = drCurrentStatus != null && drCurrentStatus.Length > 0;

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("StatusAlreadyRegistered", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "StatusAlreadyRegistered"));
            }
            return found;
        }

        /// <summary>
        /// Metodo que se encarga de hacer la llamada al servidor para actualizar la informacion de un estatus
        /// </summary>
        /// <param name="statusName">objeto con los datos a actualizar</param>
        /// <returns>true si es exitosa, false si no</returns>
        internal bool UpdateStatus(StatusEntity status)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "UpdateStatus"));

            bool isSuccess = false;
            try
            {
                isSuccess = _daoRegistryAccess.UpdateStatus(status);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("UpdateStatus", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "UpdateStatus"));
            }
            return isSuccess;
        }

        /// <summary>
        /// Metodo que se encarga de consultar un registro para saber si es igual a un parametro
        /// </summary>
        /// <param name="statusName">nombre de estatus</param>
        /// <param name="currentStatuses">coleccion de registros</param>
        /// <param name="currentStatus">registro a consultar</param>
        /// <returns>true si es el mismo registro, false si no</returns>
        internal bool IsTheSameStatus(string statusName, object currentStatuses, object currentStatus)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "IsTheSameStatus"));

            bool isSameStatus = false;
            try
            {
                DataTable dtCurrentStatuses = (DataTable)currentStatuses;
                DataRow[] drCurrentStatus = dtCurrentStatuses.Select("idStatus = " + currentStatus.ToString());
                if (drCurrentStatus != null && drCurrentStatus.Length > 0)
                    isSameStatus = drCurrentStatus[0]["statusName"].ToString() == statusName;
                else
                {
                    _logger.WriteEventViewerLog("IsTheSameStatus", Messages.failureTransactionMessage, true);
                    throw new ImperialException(Messages.failureTransactionMessage);
                }

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("IsTheSameStatus", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "IsTheSameStatus"));
            }
            return isSameStatus;
        }
    }
}